/**
 * Copyright (c) 2006-2012 Las Venturas Playground, LVP Mineground
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package mineground.core;

import java.util.ArrayList;
import java.util.concurrent.Callable;

import mineground.util.Log;

/**
 * 
 * 
 * 
 */
public class Mineground {
    /**
     * The Message Loop is the core component of the Mineground server. We own the instance and
     * are it's main consumer, responsible for communication with the native Server.
     */
    private MessageLoop mMessageLoop;
    
    /**
     * Since we are responsible for cleaning up the worker threads after execution of the Mineground
     * server has finished, we need to keep track of the threads which have been spawned.
     */
    private ArrayList<WorkerThread> mWorkerThreads = new ArrayList<WorkerThread>();
    
    /**
     * In order to properly maintain ownership of the modules available within Las Venturas
     * Mineground, the Module Registry must be used to instantiate and/or use modules.
     */
    private ModuleRegistry mModuleRegistry = new ModuleRegistry();
    
    /**
     * 
     * 
     * 
     */
    public Mineground() {
        Log.notice("---------------------------------------------------");
        Log.notice("Las Venturas Mineground - Gamemode started.");
        Log.notice("---------------------------------------------------");
        
        mMessageLoop = new MessageLoopImpl(mModuleRegistry.getMessageRouter());
        ModuleControllerBase.setMessageLoop(mMessageLoop);
        
        // Create the worker threads required for the message loop to start running business. The
        // WorkerThread class will take care of launching the threads, but we want to maintain
        // ownership for the scenario where they have to be shut down.
        mWorkerThreads.add(new WorkerThread(mMessageLoop, MessageLoopThread.GameThread, "Game Thread"));
        mWorkerThreads.add(new WorkerThread(mMessageLoop, MessageLoopThread.IOThread, "IO Thread"));
        
        // Now register the Module controllers for the different gameplay elements which we'll want
        // to listen to. Their creation will be done on the Server thread, while their usage will
        // depend on the thread requested by the caller. The registry will instantiate the class.
        mModuleRegistry.register(mineground.game.login.Controller.class);
    }
    
    /**
     * 
     * 
     */
    public void onShutdown() {
        for(int index = 0, length = mWorkerThreads.size(); index < length; ++index) {
            mWorkerThreads.get(index).requestShutdown();
        }
        
        mModuleRegistry.shutdown();
    }
    
    /**
     * We have to poll the Message Loop from the Server Thread every few milliseconds to make sure
     * that any pending commands can be executed as requested. The frequency of these calls will
     * be determined by the actual load on the server.
     */
    public void onTick() {
        mMessageLoop.run(MessageLoopThread.ServerThread);
    }
    
    /**
     * 
     * 
     */
    public MessageLoop getMessageLoop() {
        return mMessageLoop;
    }
}
